home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1993, 1994 Marc Parmet.
- * This file is part of the Macintosh port of GNU Emacs.
- *
- * GNU Emacs is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
- /*
- This implementation of alloca works by copying the register
- variable storage when allocating any space. If all register
- variables are in use, and, more data is already pushed onto the
- stack at the time of the call to alloca, then alloca will
- fail to correctly fix up the stack, resulting in an error
- far down the line.
-
- For example, if all register variables are in use, and this call is made:
- p = f(a,alloca(n),b);
- alloca will fail if b is pushed in preparation for the call to f before
- the call to alloca.
-
- This never happens in Emacs, but one day someone will hack code that uses alloca,
- and then wonder why it's crashing.
- */
-
- #include <setjmp.h>
-
- // This must be at least as big as the space needed for all register variables
- #define REGSPACE sizeof(jmp_buf)
-
- #if defined(__MWERKS__)
- asm
- #endif
- char *
- alloca(/* long n */)
- {
- #if defined(THINK_C)
- asm {
- #endif
- // Remove parameters
- move.l (a7)+,a0
- move.l (a7)+,d0
-
- // Size must be even, so round up.
- addq.l #1,d0
- bclr #0,d0
-
- // Save bottom of old register storage
- lea REGSPACE(a7),a1
-
- // Take desired space
- sub.l d0,a7
- move.l a7,d0
-
- // Copy register storage of caller
- moveq.l #(REGSPACE/4 - 1),d1
- top: move.l -(a1),-(a7)
- dbf d1,@top
-
- subq.l #4,a7 // For when the caller tries to pop the argument off the stack
- jmp (a0)
- #if defined(THINK_C)
- }
- #endif
- }
-